In computing, particularly in the context of Unix® and Unix®-like operating systems, fork is an operation whereby a process creates a copy of itself. It is usually a system call, implemented in the kernel.
In multitasking operating systems, processes (running programs) need a way to create new processes, e.g., to run other programs. Fork and its variants are typically the only way of doing so in Unix®-like systems. For a process (“parent process”) to start the execution of a different program, it first forks to create a copy of itself. Then, the copy, called the “child process,” calls the exec( ) system call to overlay itself with the other program thereby ceasing execution of its former program in favor of the other.
The fork( ) operation creates a separate address space for the child. The child process has an exact copy of all the memory segments of the parent process. In modern Unix® variants, copy-on-write system calls are implemented and the physical memory need not be actually copied. Instead, virtual memory pages in both processes may refer to the same pages of physical memory until one of them writes to such a page: then it is copied. This optimization is important in the common case where the fork( ) operation is used in conjunction with the exec( ) operation to execute a new program: typically, the child process performs only a small set of actions before it ceases execution of its program in favor of the program to be started, and it requires very few, if any, of its parent's data structures.
After the fork, both processes (parent and child) not only run the same program, but they resume execution as though both had called the system call. They can then inspect the call's return value to determine their status, child or parent, and act accordingly.
In such operations, such as creating a new process as described above, the operating system may improperly invoke the out of memory manager in response to an out of memory error to terminate processes. However, many of these processes should not be terminated. In other words, in operations to create a new process as described above, the operating system may incorrectly determine that there is insufficient memory to satisfy the request.
For example, suppose a 64-bit application is consuming 6 gigabytes of virtual memory at the moment, and it needs to create a subprocess to run the ls(1) command. The parent process issues a fork( ) system call that will succeed only if there is another 6 gigabytes of virtual memory available at the moment. If the system does not have that much virtual memory available, fork( ) will fail with an out of memory error. Such an error will occur even though the ls(1) command does not need 6 gigabytes of memory to run. As a result, the operating system improperly invokes the out of memory manager to terminate processes, including those that should not be terminated, such as essential processes that are needed to run the operating system thereby causing instability or unusability of the computing device.
One attempt to address the operating system improperly invoking the out of memory manager is to manually configure operating system settings. However, configuring operating system settings is complex and subject to error.
Another attempt to address the operating system improperly invoking the out of memory manager is to implement the vfork( ) system call. In such a system call, the parent process is suspended until the child process has either completed execution or been replaced with a new executable image via one of the “exec” family of system calls. However, the use of the vfork( ) system call requires the entire program to be rewritten.
Hence, there is currently not a means for effectively preventing the operating system from improperly invoking the out of memory manager when a system call is implemented, such as a fork( ) system call to create a new process that utilizes a copy-on-write system call.